/*
 * =====================================================================================
 *
 *        Package:  nildb
 *       Filename:  nildb.go
 *
 *    Description:  go-kissdb
 *
 *        Created:  7/2/18 9:11 PM
 *
 *         Author:  hacklog
 *            URL:  http://80x86.io
 *
 * =====================================================================================
 */
package nildb

/*
#include <stdlib.h>
#include "nildb.h"
#cgo LDFLAGS: -L.
*/
import "C"
import (
	"unsafe"
	"log"
)

var IS_DEBUG = false

func GetVersion() int {
	return C.NILDB_VERSION
}

func New() *C.nildb {
	db := &C.nildb{}
	return db
}

const COK = 0

func DbgPrintf(fmt string, val ... interface{}) {
	if IS_DEBUG {
		log.Printf(fmt, val...)
	}
}

/**
int nildb_open( nildb *db, const char *path, uint32_t hash_table_size, uint32_t key_size, uint32_t value_size);
 */
func Open(db *C.nildb, path string, hash_table_size, key_size, value_size uint32) bool {
	cpath := C.CString(path)
	rs := C.nildb_open(db, cpath, C.uint(hash_table_size), C.uint(key_size), C.uint(value_size))
	C.free(unsafe.Pointer(cpath))
	//DbgPrintf("C.nildb_open ret:%d\n", rs)
	if rs == COK {
		return true
	}
	return false
}

//nildb_close(nildb *db)
func Close(db *C.nildb) {
	C.nildb_close(db)
}

//nildb_put(nildb *db,const void *key,const void *value)
func Put(db *C.nildb, key string, value string) bool {
	ckey := unsafe.Pointer(C.CString(key))
	cvalue := unsafe.Pointer(C.CString(value))
	rs := C.nildb_put(db, ckey, cvalue)
	DbgPrintf("C.Put key:%s, val:%s, ret:%d\n", key,value, rs)
	C.free(unsafe.Pointer(ckey))
	C.free(unsafe.Pointer(cvalue))
	if rs == COK {
		return true
	}
	return false
}

//nildb_get(nildb *db,const void *key,void *vbuf);
func Get(db *C.nildb, key string, value *string) bool {
	ckey := unsafe.Pointer(C.CString(key))
	var tempVal = C.calloc(db.value_size, 1)
	if tempVal == C.NULL {
		DbgPrintf("Get C.calloc failed.")
		return false
	}
	rs := C.nildb_get(db, ckey, tempVal)
	*value = C.GoString((*C.char)(tempVal))
	DbgPrintf("Get key:%s, cvalue:%#v, ret:%d\n", key, C.GoString((*C.char)(tempVal)), rs)
	C.free(unsafe.Pointer(ckey))
	C.free(tempVal)
	if rs == COK {
		return true
	}
	return false
}
